package com.ruoyi.mongo.service;

import com.ruoyi.mongo.cet4.Entity4;
import com.ruoyi.mongo.cet4.EntityExpand4;
import com.ruoyi.mongo.cet4.EntityTestRecord;
import com.ruoyi.common.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class MongoService {

    // 注入第二个数据库的 MongoTemplate
    private final MongoTemplate secondaryMongoTemplate;

    // 构造函数注入
    public MongoService(@Qualifier("secondaryMongoTemplate") MongoTemplate secondaryMongoTemplate) {
        this.secondaryMongoTemplate = secondaryMongoTemplate;
    }

    //处理意思中包含的&
    private static String ifMeaningContainAndReturnMean(String str) {
        if (str.contains("&")) {
            int index = str.lastIndexOf(".");
            return str.substring(index + 1);
        }
        return str;
    }

    public static String[] getWordType(String str) {
        int end = getTypeEndIndex(str);
        String allType = str.substring(0, end - 1);
        if (allType.contains("&")) {
            return allType.split("&");
        }
        return new String[]{allType};
    }

    public static String getWordChinese(String str) {
        int end = getEndIndex(str);
        return ifMeaningContainAndReturnMean(str.substring(end));
    }

    private static int getTypeEndIndex(String str) {
        String regex = "[a-zA-Z]+\\.";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        int lastIndex = 1;
        while (matcher.find()) {
            lastIndex = matcher.end();
        }
        return lastIndex;
    }

    public static int getEndIndex(String str) {
        String regex = "[a-zA-Z]+\\.";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        int lastIndex = 1;
        if (matcher.find()) {
            lastIndex = matcher.end();
        }
        return lastIndex;
    }

    // 保存数据-cet4-测试记录
    public void saveTestDataList(Object document, long userId) {
        String collectionName = MongoConstants.COLLECT_CET4_TEST + "_" + userId;
        EntityTestRecord saved = (EntityTestRecord) secondaryMongoTemplate.insert(document, collectionName);
        log.info("保存-集合:{},主键:{},时间:{}", collectionName, saved.get_id(), saved.getTime());
    }

    // 保存数据-cet4-学习记录
    public void saveToSecondary(Object document, long userId) {
        String collectionName = MongoConstants.COLLECT_CET4 + "_" + userId;
        Entity4 saved = (Entity4) secondaryMongoTemplate.insert(document, collectionName);
        log.info("保存-集合:{},主键:{},时间:{}", collectionName, saved.get_id(), DateUtils.getLocalTime());
    }

    // 保存数据-cet4-拆分不同释义
    public void saveToSecondary(EntityExpand4 entity, long groupId) {
        String collectionName = MongoConstants.COLLECT_WORD_GROUP + "_expand_" + groupId;
        EntityExpand4 saved = secondaryMongoTemplate.insert(entity, collectionName);
        log.info("保存-集合:{},主键:{},时间:{}", collectionName, saved.get_id(), DateUtils.getLocalTime());
    }

    public void saveToSecondary(EntityExpand4 entity) {
        String collectionName = MongoConstants.COLLECT_ENTITY_EXPAND;
        EntityExpand4 saved = secondaryMongoTemplate.insert(entity, collectionName);
        log.info("保存-集合:{},主键:{},时间:{}", collectionName, saved.get_id(), DateUtils.getLocalTime());
    }

    public static Query getDataCommon(String unit, String book) {
        Query query = new Query();
        if (book != null && !book.isEmpty()) {
            query.addCriteria(Criteria.where(MongoConstants.MONGO_BOOK).is(book));
        }
        if (unit != null && !unit.isEmpty()) {
            Criteria criteria = Criteria.where(MongoConstants.MONGO_UNIT).is(unit);
            query.addCriteria(criteria);
        }
        return query;
    }

    public static Criteria getDataCriteria(String unit, String book) {
        Criteria criteria = new Criteria();
        if (book != null && !book.isEmpty()) {
            criteria = Criteria.where(MongoConstants.MONGO_BOOK).is(book);
        }
        if (unit != null && !unit.isEmpty()) {
            criteria = Criteria.where(MongoConstants.MONGO_UNIT).is(unit);
        }
        return criteria;
    }

    public List<Entity4> selectByPractice(String practice, String collectionName) {
        Query query = new Query();
        query.addCriteria(Criteria.where(MongoConstants.MONGO_PRACTICE).is(practice));
        List<Entity4> list = secondaryMongoTemplate.find(query, Entity4.class, collectionName);
        log.info("集合:{}-条件:{}-条数为:{}", collectionName, query.getQueryObject().toJson(), list.size());
        return list;
    }

    public List<Entity4> selectByPractice(String practice, long userId) {
        String collectionName = MongoConstants.COLLECT_CET4 + "_" + userId;
        return selectByPractice(practice, collectionName);
    }

    public List<EntityTestRecord> selectTestByPractice(String practice, String collectionName) {
        Query query = new Query();
        query.addCriteria(Criteria.where(MongoConstants.MONGO_PRACTICE).is(practice));
        List<EntityTestRecord> list = secondaryMongoTemplate.find(query, EntityTestRecord.class, collectionName);
        log.info("集合:{}-条件:{}-条数为:{}", collectionName, query.getQueryObject().toJson(), list.size());
        return list;
    }

    public List<EntityTestRecord> selectTestByPractice(String practice, long userId) {
        String collectionName = MongoConstants.COLLECT_CET4_TEST + "_" + userId;
        return selectTestByPractice(practice, collectionName);
    }

    public List<EntityExpand4> selectByType(String type,int limit){
        Query query = new Query();
        query.addCriteria(Criteria.where(MongoConstants.MONGO_TYPE).is(type));
        if (limit > 0) {
            query.limit(limit);
        }
        return secondaryMongoTemplate.find(query, EntityExpand4.class);
    }

    public List<EntityExpand4> selectByGroup(Integer group){
        Query query = new Query();
        query.addCriteria(Criteria.where(MongoConstants.MONGO_GROUP).is(group));
        List<EntityExpand4> list = secondaryMongoTemplate.find(query, EntityExpand4.class);
        log.info("集合:{}-条件:{}-条数为:{}", "entity_expand4", query.getQueryObject().toJson(), list.size());
        return list;
    }

    public List<EntityExpand4> selectByNotGroup(Integer group){
        Query query = new Query();
        query.limit(MongoConstants.MONGO_MAX_GROUP_SIZE);
        query.addCriteria(Criteria.where(MongoConstants.MONGO_GROUP).ne(group));
        List<EntityExpand4> list = secondaryMongoTemplate.find(query, EntityExpand4.class);
        log.info("集合:{}-条件:{}-条数为:{}", "entity_expand4", query.getQueryObject().toJson(), list.size());
        return list;
    }

    public List<EntityExpand4> selectNotGroupRandomData(Integer group){
        Criteria criteria = Criteria.where(MongoConstants.MONGO_GROUP).ne(group);
        return getRamdomLimitData(MongoConstants.MONGO_MAX_GROUP_SIZE,criteria).getMappedResults();
    }

    public List<EntityExpand4> selectByTypeRandom(String type,int limit){
        Query query = new Query();
        Criteria criteria = Criteria.where(MongoConstants.MONGO_TYPE).is(type);
        query.addCriteria(criteria);
        if (limit > 0) {
            query.limit(limit);
        }
        AggregationResults<EntityExpand4> aggregate = getRamdomLimitData(limit, criteria);
        return aggregate.getMappedResults();
    }

    private AggregationResults<EntityExpand4> getRamdomLimitData(int limit, Criteria criteria) {
        Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(criteria), Aggregation.sample(limit));

        String contion = criteria.getCriteriaObject().toJson();
        log.info("集合:{}-条件:{}-条数为:{}","entity_expand4",contion,limit);
        return secondaryMongoTemplate.aggregate(aggregation,
                MongoConstants.COLLECT_ENTITY_EXPAND, EntityExpand4.class);
    }
}
